package com.yonyou.brigade.order_center.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.nc.model.BaseDocRefModel;
import com.yonyou.brigade.order_center.dao.ReportMapper;
import com.yonyou.brigade.order_center.service.IReportDataService;
import com.yonyou.ybzboot.starter.common.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author houyb
 */
@Service
public class ReportDataServiceImpl implements IReportDataService {

    @Autowired
    private ReportMapper reportMapper;

    @Override
    public JSONObject getModelData(JSONObject data, HttpServletRequest request) throws Exception {
        JSONArray fields = data.getJSONArray("fields");
        JSONArray conditions = data.getJSONArray("conditions");
        JSONObject params = data.getJSONObject("params");
        JSONObject bz = params.getJSONObject("bz");
        String beginDate = bz.getString("开始日期");
        String endDate = bz.getString("截止日期");
        Integer limitSize = bz.getInteger("排名数");
        String entity = data.getString("entity");
        String tenant_id = request.getHeader("tenant_id");

        HashMap hashMap = new HashMap();
        hashMap.put("beginDate", beginDate);
        hashMap.put("endDate", endDate);
        hashMap.put("tenant", tenant_id);
        List<Map> mapList = new ArrayList<>();
        switch (entity){
            case "AirDiscount":
                mapList = reportMapper.selectAirDiscount(hashMap);
                break;
            case "AirDay":
                mapList = reportMapper.selectAirDay(hashMap);
                break;
            case "AirAdvance":
                mapList = reportMapper.selectAirAdvance(hashMap);
                break;
            case "AirLineTicket":
                String fieldName = fields.getJSONObject(0).getString("name");
                if (fieldName.contains("InnerAirLineTicket")){
                    mapList = reportMapper.selectAirLineTicket(hashMap);
                }
                if (fieldName.contains("IntAirLineTicket")){
                    mapList = reportMapper.selectIntAirLineTicket(hashMap);
                }
                break;
            case "AirRefund":
                mapList = reportMapper.selectAirRefund(hashMap);
                mapList = dealAirRefundList(mapList);
                break;
            case "AirRoute":
                mapList = reportMapper.selectAirRoute(hashMap);
                break;
            case "AirBookRank":
                hashMap.put("limitSize", limitSize);
                mapList = reportMapper.selectAirBookRank(hashMap);
                break;
            case "AirPersonBook":
                String phone = bz.getString("personPhone");
                String name = bz.getString("personName");
                if ("$$$".equals(phone)){
                    phone = "";
                }
                if ("$$$".equals(name)){
                    name = "";
                }
                if (StringUtil.isEmpty(phone) && StringUtil.isEmpty(name)){
                    break;
                }
                hashMap.put("phone", phone);
                hashMap.put("name", name);
                fieldName = fields.getJSONObject(0).getString("name");
                if (fieldName.contains("InnerAirLineTicket")){
                    mapList = reportMapper.selectAirPersonBook(hashMap);
                }
                if (fieldName.contains("AirDiscount")){
                    mapList = reportMapper.selectAirDiscountV2(hashMap);
                    mapList = dealAirDiscountList(mapList);
                }
                break;
            case "UnSelectLowersReason":
                mapList = reportMapper.selectUnSelectLowersReason(hashMap);
                break;
            default :
                break;
        }
        List<List> resultArr = new ArrayList<>();
        int rankNo = 1;
        for (Map map : mapList) {
            List resultValue = new ArrayList();
            for (int i = 0; i < fields.size(); i++) {
                JSONObject field = fields.getJSONObject(i);
                String fieldName= field.getString("name");
                if (fieldName.contains(".")){
                    resultValue.add(map.get(fieldName.split("\\.")[1]));
                }else {
                    if ("rankNo".equals(fieldName) && "AirBookRank".equals(entity)){
                        resultValue.add(rankNo);
                    }else {
                        resultValue.add(map.get(fieldName));
                    }
                }
            }
            rankNo++;
            resultArr.add(resultValue);
        }

        JSONArray metaArr = new JSONArray();
        for (int i = 0; i < fields.size(); i++) {
            JSONObject field = fields.getJSONObject(i);
            String fieldName= field.getString("name");
            JSONObject meta = new JSONObject();
            meta.put("entity", entity);
            meta.put("code", fieldName);
            metaArr.add(meta);
        }
        //res返回的结果集
        JSONObject res = new JSONObject();
        res.put("result", resultArr);
        res.put("meta", metaArr);
        return res;
    }

    private List<Map> dealAirRefundList(List<Map> list){
        List<Map> showMapList = new ArrayList<>();
        for (Map map : list) {
            if (map == null){
                continue;
            }
            Map nMap = new HashMap();
            nMap.put("type","正常票");
            nMap.put("ticketNum",map.get("ticketNum"));
            nMap.put("ticketMoney",map.get("ticketMoney"));
            showMapList.add(nMap);
            Map rMap = new HashMap();
            rMap.put("type","退票");
            rMap.put("ticketNum",map.get("refundedTicketNum"));
            rMap.put("ticketMoney",map.get("refundedTicketMoney"));
            showMapList.add(rMap);
        }
        return showMapList;
    }

    /**
     * 处理折扣查询结果
     * @param list
     * @return
     */
    private List<Map> dealAirDiscountList(List<Map> list){
        List<Map> rsList = new ArrayList<>();
        if (list.size() > 0){
            Map map = list.get(0);
            if (map == null){
                return rsList;
            }
            for (Object key : map.keySet()) {
                Map resultMap = new HashMap();
                String newKey = "";
                switch (key.toString()){
                    case "0":
                        newKey = "0.1-0.9";
                        break;
                    case "1":
                        newKey = "1.0-1.9";
                        break;
                    case "2":
                        newKey = "2.0-2.9";
                        break;
                    case "3":
                        newKey = "3.0-3.9";
                        break;
                    case "4":
                        newKey = "4.0-4.9";
                        break;
                    case "5":
                        newKey = "5.0-5.9";
                        break;
                    case "6":
                        newKey = "6.0-6.9";
                        break;
                    case "7":
                        newKey = "7.0-7.9";
                        break;
                    case "8":
                        newKey = "8.0-8.9";
                        break;
                    case "9":
                        newKey = "9.0及以上";
                        break;
                }
                resultMap.put("discount", newKey);
                resultMap.put("ticketNum", map.get(key));
                rsList.add(resultMap);
            }
        }
        return rsList;

    }

    /**
     * 当前属性包括聚合方式时
     * @param name
     * @return
     */
    private String getAggrName(String name){
        if(name.contains("model")){
            if(name.split("\\.").length == 1){
                name = name.substring(0, name.indexOf("model")) + "pk";
            }else{
                name = name.substring(name.indexOf(".") + 1);
                if(name.contains("name")){
                    //当前有name时，无法查询
                    name = "";
                }
            }
        }
        return name;
    }

    /**
     * 根据数据权限 查询的id，拼接 in ()方式的查询条件
     * @param docString
     * @return
     */
    private String dataPermissionsCondition(String docString){
        String dataPermissionsPk = "";
        if(docString != null && !"".equalsIgnoreCase(docString)){
            JSONObject docObject = JSONObject.parseObject(docString);
            if(docObject.getBoolean("success")) {
                JSONArray data = docObject.getJSONArray("data");
                if (data != null && data.size() != 0) {
                    StringBuilder dataPermissionsPkBuilder = new StringBuilder(dataPermissionsPk);
                    for (int i = 0; i < data.size(); i++) {
                        JSONObject jsonObject = data.getJSONObject(i);
                        dataPermissionsPkBuilder.append("'").append(jsonObject.getString("id")).append("'").append(",");
                    }
                    dataPermissionsPk = dataPermissionsPkBuilder.toString();
                    dataPermissionsPk = "(" + dataPermissionsPk.substring(0, dataPermissionsPk.length() - 1) + ")";
                }
            }
        }
        return dataPermissionsPk;
    }

    /**
     * 根据数据权限 查询的id，拼接 in ()方式的查询条件,方法重构，为NC提供
     * @param refModels
     * @return
     */
    private String dataPermissionsCondition(List<BaseDocRefModel> refModels){
        String dataPermissionsPk = "";
        if(refModels != null && refModels.size() != 0){
            StringBuilder dataPermissionsPkBuilder = new StringBuilder(dataPermissionsPk);
            for (int i = 0; i < refModels.size(); i++) {
                dataPermissionsPkBuilder.append("'").append(refModels.get(i).getId()).append("'").append(",");
            }
            dataPermissionsPk = dataPermissionsPkBuilder.toString();
            dataPermissionsPk = "(" + dataPermissionsPk.substring(0, dataPermissionsPk.length() - 1) + ")";
        }
        return dataPermissionsPk;
    }

    /**
     * NCC和saas获取参照时，传入的type不一致
     * @param jsonObject
     * @param env
     * @return
     */
    private String getRefType(JSONObject jsonObject, String env){
        String refType = null;
        if(jsonObject.getString("name").contains("orgmodel") || jsonObject.getString("name").contains("adminorgmodel")){
            if("nc".equals(env)){
                //之前为行政组织，行政组织会参照不全，现全部改成 业务单元，业务单元是查询所有的组织
                refType = "业务单元";
            }else {
                refType = "";
            }
        }else if (jsonObject.getString("name").contains("deptmodel") || jsonObject.getString("name").contains("reimbursedeptmodel")){
            if("nc".equals(env)){
                refType = "部门";
            }else {
                refType = "";
            }
        }else if (jsonObject.getString("name").contains("projectmodel")){
            if("nc".equals(env)){
                refType = "项目";
            }else {
                refType = "";
            }
        }else if (jsonObject.getString("name").contains("feeitemmodel")){
            if("nc".equals(env)){
                refType = "收支项目";
            }else {
                refType = "";
            }
        }else if (jsonObject.getString("name").contains("currencymodel")){
            if("nc".equals(env)){
                refType = "币种档案";
            }else {
                refType = "";
            }
        }

        return refType;
    }

    /**
     * 在报表编辑页面会设置过滤条件，设置过滤后，一般为xx != '',与后面的权限设置 xx = ''，存在冲突
     * 所以当前面设置了 xx != ''时，后面权限控制时，不能再设置 xx = '',该方法就是用于判断前面是否设置了xx != ''(还要结合queryInfo这个判断)
     * type要为固定的childrenref的形式，前台传过来的参数形式可能存在多种情况
     * @param fieldArray
     * @param type
     * @return
     */
    private boolean isFiltrationConditions(JSONArray fieldArray, String type){
        JSONObject jsonObjectTmp;
        boolean isFilter = false;
        String[] types = type.split("\\.");
        for (int i = 0; i < fieldArray.size(); i++) {
            jsonObjectTmp = fieldArray.getJSONObject(i);
            String name = jsonObjectTmp.getString("name");
            if(type.equals(name) || types[0].equals(name) || types[1].equals(name)){
                isFilter = true;
                break;
            }
        }

        return isFilter;
    }

    /**
     * 根据status状态码获取对应的支付状态名称，多语
     * NC中，支付状态是1/2/3/4/20/99
     * @param status
     * @param locale
     * @return
     */
    private String getPayStatus(String status, String locale){
        String res = "";
        switch(status){
            case "notpay" :
            case "1" :
                switch (locale){
                    case "zh_CN" :
                    case "zh_TW" :
                        res = "未支付";
                        break;
                    case "en_US" :
                        res = "Unpaid";
                }
                break;
            case "paysucess" :
            case "3" :
                switch (locale){
                    case "zh_CN" :
                    case "zh_TW" :
                        res = "已支付";
                        break;
                    case "en_US" :
                        res = "Payment Completed";
                }
                break;
            case "paying" :
            case "2" :
                switch (locale){
                    case "zh_CN" :
                    case "zh_TW" :
                        res = "支付中";
                        break;
                    case "en_US" :
                        res = "Being Paid";
                }
                break;
            case "payfail" :
            case "4" :
                switch (locale){
                    case "zh_CN" :
                        res = "支付失败";
                        break;
                    case "en_US" :
                        res = "Payment Failed";
                        break;
                    case "zh_TW" :
                        res = "支付失敗";
                }
                break;
            case "20" :
                switch (locale){
                    case "zh_CN" :
                    case "zh_TW" :
                        res = "部分支付完成";
                        break;
                    case "en_US" :
                        res = "Partial Payment Completed";
                }
                break;
            case "99" :
                switch (locale){
                    case "zh_CN" :
                    case "zh_TW" :
                        res = "手工支付";
                        break;
                    case "en_US" :
                        res = "Manual Payment";
                }
                break;
            case "101" :
                switch (locale){
                    case "zh_CN" :
                        res = "全额冲销";
                        break;
                    case "en_US" :
                        res = "Full Amt Reversal";
                        break;
                    case "zh_TW" :
                        res = "全額沖銷";
                }
                break;
            case "102" :
                switch (locale){
                    case "zh_CN" :
                        res = "调整";
                        break;
                    case "en_US" :
                        res = "Adjust";
                        break;
                    case "zh_TW" :
                        res = "調整";
                }
        }

        return res;
    }

    /**
     * 根据status状态码获取对应的单据状态名称，多语
     * @param status
     * @param locale
     * @return
     */
    private String getBillStatus(String status, String locale){
        String res = "";
        switch(status) {
            case "3":
                switch (locale) {
                    case "zh_CN":
                        res = "已提交";
                        break;
                    case "en_US":
                        res = "Submitted";
                        break;
                    case "zh_TW":
                        res = "已提交";
                }
                break;
            case "4":
                switch (locale) {
                    case "zh_CN":
                        res = "审批中";
                        break;
                    case "en_US":
                        res = "In approval";
                        break;
                    case "zh_TW":
                        res = "審批中";
                }
                break;
            case "5":
                switch (locale) {
                    case "zh_CN":
                        res = "审批完成";
                        break;
                    case "en_US":
                        res = "Approved";
                        break;
                    case "zh_TW":
                        res = "審批完成";
                }
        }

        return res;
    }


}
